package dwarffortress.analysis;

import java.lang.reflect.Field;

public class ObjectAnalyzer<T> {
    Object object;
    private StructureAnalyzer<T> structure;

    ObjectAnalyzer(StructureAnalyzer<T> structure, T object) {
        this.object = object;
        this.structure = structure;
    }

    public int getFieldCount() {
        return structure.getFieldCount();
    }

    public boolean isArray(int index) {
        return structure.isArray(index);
    }

    public int getArrayLength(int index) throws IllegalAccessException {
        Field field = structure.getField(index);
        Class<?> arrayType = field.getType().getComponentType();
        Object fieldValue = field.get(object);
        if (null == fieldValue) {
            System.out.println("StructureAnalyzer.getArrayLength");
        }
        if (!arrayType.isPrimitive()) {
            return ((Object[]) fieldValue).length;
        } else if (arrayType.equals(Integer.TYPE)) {
            return ((int[]) fieldValue).length;
        } else if (arrayType.equals(Short.TYPE)) {
            return ((short[]) fieldValue).length;
        } else if (arrayType.equals(Byte.TYPE)) {
            return ((byte[]) fieldValue).length;
        } else if (arrayType.equals(Boolean.TYPE)) {
            return ((boolean[]) fieldValue).length;
        }
        throw new IllegalStateException("Some strange type of array element");
    }

    public int getIntValue(int index) throws IllegalAccessException {
        Field field = structure.getField(index);
        Class<?> type = field.getType();

        if (!type.isPrimitive()) {
            throw new IllegalStateException("Field is not a primitive ");
        } else if (type.equals(Integer.TYPE)) {
            return field.getInt(object);
        } else if (type.equals(Short.TYPE)) {
            return field.getShort(object);
        } else if (type.equals(Byte.TYPE)) {
            return field.getByte(object);
        }
        throw new IllegalStateException("Field can not be converted to int");

    }

    public boolean isLoadable(int index) {
        return structure.isLoadable(index);
    }

    public void setValue(int index, Object value) throws IllegalAccessException {
        structure.getField(index).set(object, value);
    }

    public void setIntValue(int index, int value) throws IllegalAccessException {
        structure.getField(index).setInt(object, value);
    }

    public void setShortValue(int index, short value) throws IllegalAccessException {
        structure.getField(index).setShort(object, value);
    }

    public void setByteValue(int index, byte value) throws IllegalAccessException {
        structure.getField(index).setByte(object, value);
    }
}